package com.deep.ware.handler;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.deep.common.model.dto.OrderDTO;
import com.deep.common.model.dto.mq.StockDetailDTO;
import com.deep.common.model.dto.mq.StockLockedDTO;
import com.deep.common.model.enume.OrderStatusEnum;
import com.deep.common.utils.R;
import com.deep.ware.feign.OrderFeignService;
import com.deep.ware.model.entity.WareOrderTaskDetailEntity;
import com.deep.ware.model.entity.WareOrderTaskEntity;
import com.deep.ware.model.entity.WareSkuEntity;
import com.deep.ware.model.vo.OrderVO;
import com.deep.ware.service.WareOrderTaskDetailService;
import com.deep.ware.service.WareOrderTaskService;
import com.deep.ware.service.WareSkuService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * RabbitMQ消息监听
 *
 * @author Deep
 * @date 2022/2/18
 */
@Slf4j
@Component
@RabbitListener(queues = "stock.release.stock.queue")
public class WareRabbitMQHandler {

    @Autowired
    private WareOrderTaskService wareOrderTaskService;
    @Autowired
    private WareOrderTaskDetailService wareOrderTaskDetailService;
    @Autowired
    private WareSkuService wareSkuService;
    @Autowired
    private OrderFeignService orderFeignService;

    /**
     * 库存解锁（超时解锁）
     */
    @RabbitHandler
    public void stockReleaseHandler(StockLockedDTO lockedDTO, Message message, Channel channel) throws IOException {
        Long orderTaskId = lockedDTO.getId();    // 订单id
        log.info("解锁库存，订单ID：{}", orderTaskId);
        StockDetailDTO detailDTO = lockedDTO.getDetailTo();
        // 回滚解锁（超时取消订单、客户手动取消订单、有商品项没有锁住）
        // 1、查询数据库该订单的锁库存信息[没有工作详情单：商品项锁定时失败(无需回滚)；有工作详情单：无订单/超时/手动取消订单(回滚)]
        WareOrderTaskDetailEntity orderTaskDetailEntity = wareOrderTaskDetailService.getById(detailDTO.getId());
        if (orderTaskDetailEntity != null) {
            // 有工作详情单
            // 1、查询订单
            WareOrderTaskEntity orderTaskEntity = wareOrderTaskService.getById(orderTaskId);
            String orderSn = orderTaskEntity.getOrderSn();  // 获取订单号
            OrderVO orderVO = orderFeignService.getOrderStatus(orderSn);
            if (orderVO != null) {
                unLockStock(detailDTO.getSkuId(), detailDTO.getWareId(), detailDTO.getSkuNum(), detailDTO.getId());
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }
            /*if (orderVO == null || OrderStatusEnum.CANCLED.getCode().equals(orderVO.getStatus())) {
                // 订单不存在/订单已取消
                unLockStock(detailDTO.getSkuId(), detailDTO.getWareId(), detailDTO.getSkuNum(), detailDTO.getId());
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }*/
            else {
                // 消息拒绝解锁(重新放回队列)
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
            }
        } else {
            // 无工作详情单
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
    }

    /**
     * 库存解锁（防止服务器卡顿）
     */
    @RabbitHandler
    public void handleOrderCloseRelease(OrderDTO orderDTO, Message message, Channel channel) throws IOException {
        System.out.println("******收到订单关闭，准备解锁库存的信息******订单号：" + orderDTO.getOrderSn());
        try {
            int count = wareSkuService.unlockStock(orderDTO);
            // 手动删除消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 解锁失败 将消息重新放回队列，让别人消费
            channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
        }
    }


    private void unLockStock(Long skuId, Long wareId, Integer num, Long taskDetailId) {
        // 解锁库存
        int count = wareSkuService.unLockStock(skuId, wareId, num);
        if (count != 1) {
            // 解锁失败
            throw new RuntimeException("解锁失败!");
        }
        // 删除详情单
        wareOrderTaskDetailService.removeById(taskDetailId);
    }
}
